/******************************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Ltd.                       */
/*                                                                            */
/*  NAME      = frkryo.c                                                      */
/*  NOTE      = Kryo序列化解析                                                */
/*  DATE      = 2016/01/16 by zhengxd                                         */
/******************************************************************************/
#include <stdlib.h>
#include <stdio.h>

#include "frcomm.h"
#include "frmem.h"
#include "frreport_comm.h"
#include "frbyte_buffer.h"
#include "frkyro.h"

#define FRKYRO_CLASS_NAME           1
#define FRKYRO_NULL                 0
#define FRKYRO_NOT_NULL             1

/*******************************************************************************
*  FUNC     :  取得ascii
*  ARGS     :  p_st_data(Frbyte_Packet *)
*           :  u8_first_char(首直接)
*           :  pp_ascii_value(取得string)
*  RTN      :  FR_SUCC  (success)
*              FR_FAIL  (failed)
*  NOTE     :
*******************************************************************************/
int frkyro_read_ascii(Frbyte_Packet *p_st_data
                      , uint8_t u8_first_char
                      , char **pp_ascii_value)
{
    int i_ret = FR_SUCC;
    uint8_t u8_one_char = u8_first_char;
    char *p_ascii_value = NULL;
    char *p_tmp = NULL;
    unsigned int ui_value_size = 128;
    unsigned int ui_loop = 0;

    /* 用于存放内容 */
    p_ascii_value = (char *)frmalloc(ui_value_size);
    if (p_ascii_value == NULL)
    {
        return FR_FAIL;
    }

    while ((u8_one_char & 0x80) == 0)
    {
        /* 原来的内存不足 */
        if (ui_loop >= ui_value_size - 1)
        {
            ui_value_size *= 2;
            p_tmp = (char *)frmalloc(ui_value_size);
            if (p_tmp == NULL)
            {
                frfree(p_ascii_value);
                return FR_FAIL;
            }
            memcpy(p_tmp, p_ascii_value, ui_loop + 1);
            frfree(p_ascii_value);
            p_ascii_value = p_tmp;
        }
        p_ascii_value[ui_loop++] = (char)u8_one_char;
        /* 取得下一个字节 */
        i_ret = bytebuff_get_char(p_st_data, &u8_one_char);
        if (i_ret != FR_SUCC)
        {
            frfree(p_ascii_value);
            return FR_FAIL;
        }
    }
    /* 最后一个字节需要与上0x7F */
    u8_one_char &= 0x7F;
    p_ascii_value[ui_loop++] = (char)u8_one_char;
    p_ascii_value[ui_loop] = '\0';

    *pp_ascii_value = p_ascii_value;
    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  取得utf8 string
*  ARGS     :  p_st_data(Frbyte_Packet *)
*           :  u8_first_char(首直接)
*           :  pp_ascii_value(取得string)
*  RTN      :  FR_SUCC  (success)
*              FR_FAIL  (failed)
*  NOTE     :
*******************************************************************************/
int frkyro_read_utf8(Frbyte_Packet *p_st_data
                     , uint8_t u8_first_char
                     , char **pp_utf8_value)
{
    int i_ret = FR_SUCC;
    int i_loop = 0;
    uint8_t u8_one_char = u8_first_char;
    int i_uft8_len = u8_one_char & 0x3F;
    char arr_bytes[3] = {0};
    char *p_utf8_value = NULL;

    /* 取得utf-8长度(不是字节数，而是文字格式) */
    if ((u8_one_char & 0x40) != 0)  // Bit 7 means another byte, bit 8 means UTF8.
    {
        i_ret = bytebuff_get_char(p_st_data, &u8_one_char);
        if (i_ret != FR_SUCC)
        {
            return FR_FAIL;
        }
        i_uft8_len |= (u8_one_char & 0x7F) << 6;
	    if ((u8_one_char & 0x80) != 0)
	    {
            i_ret = bytebuff_get_char(p_st_data, &u8_one_char);
            if (i_ret != FR_SUCC)
            {
                return FR_FAIL;
            }
			i_uft8_len |= (u8_one_char & 0x7F) << 13;
			if ((u8_one_char & 0x80) != 0)
			{
                i_ret = bytebuff_get_char(p_st_data, &u8_one_char);
                if (i_ret != FR_SUCC)
                {
                    return FR_FAIL;
                }
                i_uft8_len |= (u8_one_char & 0x7F) << 20;
                if ((u8_one_char & 0x80) != 0) {
                    i_ret = bytebuff_get_char(p_st_data, &u8_one_char);
                    if (i_ret != FR_SUCC)
                    {
                        return FR_FAIL;
                    }
                    i_uft8_len |= (u8_one_char & 0x7F) << 27;
                }
			}
		}
    }

    /* 很据长度取得utf8 string */
	switch (i_uft8_len)
	{
	    case 0:
	        *pp_utf8_value = NULL;
			return FR_SUCC;
		case 1:
	        *pp_utf8_value = frstrdup("");
			return FR_SUCC;
	}

    /* 申请足够长的空间 */
    p_utf8_value = (char *)frmalloc(i_uft8_len * 3 + 1);
    if (p_utf8_value == NULL)
    {
        return FR_FAIL;
    }
    i_uft8_len--;

    while (i_uft8_len--)
    {
        /* 取得一个字节 */
        i_ret = bytebuff_get_char(p_st_data, &u8_one_char);
        if (i_ret != FR_SUCC)
        {
            return FR_FAIL;
        }
        /* 根据该字节判断改utf8文字有几个字节组成 */
        switch (u8_one_char >> 4)
        {
            /* 单字节文字 */
			case 0:
			case 1:
			case 2:
			case 3:
			case 4:
			case 5:
			case 6:
			case 7:
				p_utf8_value[i_loop++] = (char)u8_one_char;
				break;

            /* 双字节文字 */
            case 12:
            case 13:
                p_utf8_value[i_loop++] = (char)u8_one_char;
                /* 取下一个字节 */
                i_ret = bytebuff_get_char(p_st_data, &u8_one_char);
                if (i_ret != FR_SUCC)
                {
                    frfree(p_utf8_value);
                    return FR_FAIL;
                }
                p_utf8_value[i_loop++] = (char)u8_one_char;
                break;

            /* 三字节文字 */
            case 14:
				p_utf8_value[i_loop++] = (char)u8_one_char;
                i_ret = bytebuff_get_bytes(p_st_data, arr_bytes, 2);
                if (i_ret != FR_SUCC)
                {
                    frfree(p_utf8_value);
                    return FR_FAIL;
                }
                arr_bytes[2] = '\0';
                snprintf(p_utf8_value + i_loop, 3, "%s", arr_bytes);
                i_loop += 2;
                break;
        }
    }
    p_utf8_value[i_loop] = '\0';
    *pp_utf8_value = p_utf8_value;
    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  取得string
*  ARGS     :  p_st_data(Frbyte_Packet *)
*           :  pp_string_value(取得string)
*  RTN      :  FR_SUCC  (success)
*              FR_FAIL  (failed)
*  NOTE     :
*******************************************************************************/
int frkyro_read_string(Frbyte_Packet *p_st_data
                       , char **pp_string_value)
{
    int i_ret = FR_SUCC;
    uint8_t u8_first_char = 0;

    i_ret = bytebuff_get_char(p_st_data, &u8_first_char);
    if (i_ret != FR_SUCC)
    {
        return FR_FAIL;
    }

    /* 根据第一个字节来判断是ascii还是utf8string */
    if ((u8_first_char & 0x80) == 0)
    {
        i_ret = frkyro_read_ascii(p_st_data, u8_first_char, pp_string_value);
    }
    else
    {
        i_ret =  frkyro_read_utf8(p_st_data, u8_first_char, pp_string_value);
    }
    return i_ret;
}

/*******************************************************************************
*  FUNC     :  取得可变长度long值
*  ARGS     :  p_st_data(Frbyte_Packet *)
*           :  i_optimize_flg(优化表示FR_YES/FR_NO)
*           :  p_l_value(取得long值)
*  RTN      :  FR_SUCC  (success)
*              FR_FAIL  (failed)
*  NOTE     :
*******************************************************************************/
int frkyro_read_var_long(Frbyte_Packet *p_st_data
                         , int i_optimize_flg
                         , long *p_l_value)
{
    int i_ret = FR_SUCC;
    long l_value = 0;
    uint8_t u8_one_byte = 0;

    i_ret = bytebuff_get_char(p_st_data, &u8_one_byte);
    if (i_ret != FR_SUCC)
    {
        return FR_FAIL;
    }
    l_value = u8_one_byte & 0x7F;
    if ((u8_one_byte & 0x80) != 0)
    {
        i_ret = bytebuff_get_char(p_st_data, &u8_one_byte);
        if (i_ret != FR_SUCC)
        {
            return FR_FAIL;
        }
        l_value |= (u8_one_byte & 0x7F) << 7;
        if ((u8_one_byte & 0x80) != 0)
        {
            i_ret = bytebuff_get_char(p_st_data, &u8_one_byte);
            if (i_ret != FR_SUCC)
            {
                return FR_FAIL;
            }
            l_value |= (u8_one_byte & 0x7F) << 14;
            if ((u8_one_byte & 0x80) != 0)
            {
                i_ret = bytebuff_get_char(p_st_data, &u8_one_byte);
                if (i_ret != FR_SUCC)
                {
                    return FR_FAIL;
                }
                l_value |= (u8_one_byte & 0x7F) << 21;
                if ((u8_one_byte & 0x80) != 0)
                {
                    i_ret = bytebuff_get_char(p_st_data, &u8_one_byte);
                    if (i_ret != FR_SUCC)
                    {
                        return FR_FAIL;
                    }
                    l_value |= (u8_one_byte & 0x7F) << 28;
                    if ((u8_one_byte & 0x80) != 0)
                    {
                        i_ret = bytebuff_get_char(p_st_data, &u8_one_byte);
                        if (i_ret != FR_SUCC)
                        {
                            return FR_FAIL;
                        }
                        l_value |= (long)(u8_one_byte & 0x7F) << 35;
                        if ((u8_one_byte & 0x80) != 0)
                        {
                            i_ret = bytebuff_get_char(p_st_data, &u8_one_byte);
                            if (i_ret != FR_SUCC)
                            {
                                return FR_FAIL;
                            }
                            l_value |= (long)(u8_one_byte & 0x7F) << 42;
                            if ((u8_one_byte & 0x80) != 0)
                            {
                                i_ret = bytebuff_get_char(p_st_data, &u8_one_byte);
                                if (i_ret != FR_SUCC)
                                {
                                    return FR_FAIL;
                                }
                                l_value |= (long)(u8_one_byte & 0x7F) << 49;
                                if ((u8_one_byte & 0x80) != 0)
                                {
                                    i_ret = bytebuff_get_char(p_st_data, &u8_one_byte);
                                    if (i_ret != FR_SUCC)
                                    {
                                        return FR_FAIL;
                                    }
                                    l_value |= (long)u8_one_byte << 56;
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    if (i_optimize_flg == FR_YES)
    {
        *p_l_value = (l_value >> 1) ^ -(l_value & 1);
    }
    else
    {
        *p_l_value = l_value;
    }
    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  取得可变长度int值
*  ARGS     :  p_st_data(Frbyte_Packet *)
*           :  i_optimize_flg(优化表示FR_YES/FR_NO)
*           :  p_l_value(取得int值)
*  RTN      :  FR_SUCC  (success)
*              FR_FAIL  (failed)
*  NOTE     :
*******************************************************************************/
int frkyro_read_var_int(Frbyte_Packet *p_st_data
                        , int i_optimize_flg
                        , int *p_i_value)
{
    int i_ret = FR_SUCC;
    int i_value = 0;
    uint8_t u8_one_byte = 0;

    i_ret = bytebuff_get_char(p_st_data, &u8_one_byte);
    if (i_ret != FR_SUCC)
    {
        return FR_FAIL;
    }
    i_value = u8_one_byte & 0x7F;
    if ((u8_one_byte & 0x80) != 0)
    {
        i_ret = bytebuff_get_char(p_st_data, &u8_one_byte);
        if (i_ret != FR_SUCC)
        {
            return FR_FAIL;
        }
        i_value |= (u8_one_byte & 0x7F) << 7;
        if ((u8_one_byte & 0x80) != 0)
        {
            i_ret = bytebuff_get_char(p_st_data, &u8_one_byte);
            if (i_ret != FR_SUCC)
            {
                return FR_FAIL;
            }
            i_value |= (u8_one_byte & 0x7F) << 14;
            if ((u8_one_byte & 0x80) != 0)
            {
                i_ret = bytebuff_get_char(p_st_data, &u8_one_byte);
                if (i_ret != FR_SUCC)
                {
                    return FR_FAIL;
                }
                i_value |= (u8_one_byte & 0x7F) << 21;
                if ((u8_one_byte & 0x80) != 0)
                {
                    i_ret = bytebuff_get_char(p_st_data, &u8_one_byte);
                    if (i_ret != FR_SUCC)
                    {
                        return FR_FAIL;
                    }
                    i_value |= (u8_one_byte & 0x7F) << 28;
                }
            }
        }
    }

    if (i_optimize_flg == FR_YES)
    {
        *p_i_value = (i_value >> 1) ^ -(i_value & 1);
    }
    else
    {
        *p_i_value = i_value;
    }
    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  倒序读取字节
*  ARGS     :  p_st_data(Frbyte_Packet *)
*           :  i_size(要取得的字节数)
*           :  p_value(内容)
*  RTN      :  FR_SUCC  (success)
*              FR_FAIL  (failed)
*  NOTE     :
*******************************************************************************/
int frkyro_read_inverted_bytes(Frbyte_Packet *p_st_data
                                , int i_size
                                , char *p_value)
{
    int i_ret = FR_SUCC;
    char arr_bytes[i_size + 1];
    int i_loop = 0;

    i_ret = bytebuff_get_bytes(p_st_data, arr_bytes, i_size);
    if (i_ret != FR_SUCC)
    {
        return FR_FAIL;
    }

    while (i_loop < i_size)
    {
        p_value[i_loop] = arr_bytes[i_size - 1 - i_loop];
        i_loop++;
    }
    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  读取float值
*  ARGS     :  p_st_data(Frbyte_Packet *)
*           :  p_f_value(取得float值)
*  RTN      :  FR_SUCC  (success)
*              FR_FAIL  (failed)
*  NOTE     :
*******************************************************************************/
int frkyro_read_float(Frbyte_Packet *p_st_data, float *p_f_value)
{
    int i_ret = FR_SUCC;
    char arr_bytes[sizeof(float)] = {0};

    i_ret = frkyro_read_inverted_bytes(p_st_data, sizeof(float), arr_bytes);
    if (i_ret != FR_SUCC)
    {
        return FR_FAIL;
    }
    memcpy(p_f_value, arr_bytes, sizeof(float));
    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  读取double值
*  ARGS     :  p_st_data(Frbyte_Packet *)
*           :  p_d_value(取得double值)
*  RTN      :  FR_SUCC  (success)
*              FR_FAIL  (failed)
*  NOTE     :
*******************************************************************************/
int frkyro_read_double(Frbyte_Packet *p_st_data, double *p_d_value)
{
    int i_ret = FR_SUCC;
    char arr_bytes[sizeof(double)] = {0};

    i_ret = frkyro_read_inverted_bytes(p_st_data, sizeof(double), arr_bytes);
    if (i_ret != FR_SUCC)
    {
        return FR_FAIL;
    }
    memcpy(p_d_value, arr_bytes, sizeof(double));
    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  取得int值
*  ARGS     :  p_st_data(Frbyte_Packet *)
*           :  p_i_value(取得int值)
*  RTN      :  FR_SUCC  (success)
*              FR_FAIL  (failed)
*  NOTE     :
*******************************************************************************/
int frkyro_read_int(Frbyte_Packet *p_st_data, int *p_i_value)
{
    int i_ret = FR_SUCC;
    char arr_bytes[5] = {0};
    int i_value = 0;

    i_ret = bytebuff_get_bytes(p_st_data, arr_bytes, 4);
    if (i_ret != FR_SUCC)
    {
        return FR_FAIL;
    }

    i_value = (unsigned char)arr_bytes[0];
    i_value = (i_value << 8) | (unsigned char)arr_bytes[1];
    i_value = (i_value << 8) | (unsigned char)arr_bytes[2];
    i_value = (i_value << 8) | (unsigned char)arr_bytes[3];
    *p_i_value = i_value;
    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  取得int值
*  ARGS     :  p_s_value(Frbyte_Packet *)
*           :  p_s_value(取得short值)
*  RTN      :  FR_SUCC  (success)
*              FR_FAIL  (failed)
*  NOTE     :
*******************************************************************************/
int frkyro_read_short(Frbyte_Packet *p_st_data, short *p_s_value)
{
    int i_ret = FR_SUCC;
    char arr_bytes[3] = {0};
    short s_value = 0;

    i_ret = bytebuff_get_bytes(p_st_data, arr_bytes, 2);
    if (i_ret != FR_SUCC)
    {
        return FR_FAIL;
    }

    s_value = (unsigned char)arr_bytes[0];
    s_value = (s_value << 8) | (unsigned char)arr_bytes[1];
    *p_s_value = s_value;
    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  取得char(java char是双字节的)
*  ARGS     :  p_st_data(Frbyte_Packet *)
*           :  pp_value(双字节的char)
*  RTN      :  FR_SUCC  (success)
*              FR_FAIL  (failed)
*  NOTE     :
*******************************************************************************/
int frkyro_read_char(Frbyte_Packet *p_st_data, char **pp_value)
{
    int i_ret = FR_SUCC;
    char arr_bytes[3] = {0};
    char *p_value = NULL;
    int i_index = 0;

    i_ret = bytebuff_get_bytes(p_st_data, arr_bytes, 2);
    if (i_ret != FR_SUCC)
    {
        return FR_FAIL;
    }

    p_value = (char *)frmalloc(2 + 1);
    if (p_value == NULL)
    {
        return FR_FAIL;
    }
    *pp_value = p_value;
    if (arr_bytes[0] != '\0')
    {
        p_value[i_index++] = arr_bytes[0];
    }
    p_value[i_index++] = arr_bytes[1];
    p_value[i_index] = '\0';
    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  取得byte
*  ARGS     :  p_st_data(Frbyte_Packet *)
*           :  pp_value(单字节的byte)
*  RTN      :  FR_SUCC  (success)
*              FR_FAIL  (failed)
*  NOTE     :
*******************************************************************************/
int frkyro_read_byte(Frbyte_Packet *p_st_data, char **pp_value)
{
    int i_ret = FR_SUCC;
    char *p_value = NULL;

    p_value = (char *)frmalloc(1 + 1);
    if (p_value == NULL)
    {
        return FR_FAIL;
    }
    i_ret = bytebuff_get_bytes(p_st_data, p_value, 1);
    if (i_ret != FR_SUCC)
    {
        frfree(p_value);
        return FR_FAIL;
    }

    p_value[1] = '\0';
    *pp_value = p_value;
    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  读取class
*  ARGS     :  p_st_data(Frbyte_Packet *)
*           :  p_st_body_data(上报内容)
*           :  i_is_request(是否是request)
*           :  p_i_end_flg(结束flag)
*  RTN      :  FR_SUCC  (success)
*              FR_FAIL  (failed)
*  NOTE     :
*******************************************************************************/
int frkyro_read_class(Frbyte_Packet *p_st_data
                      , Frreport_body_data *p_st_body_data
                      , int i_is_request
                      , int *p_i_end_flg)
{
    int i_ret = FR_SUCC;
    int i_class_id = 0;
    int i_name_id = 0;
    int i_position = 0;
    char *p_class_name = NULL;
    char arr_key[256] = {0};
    char *p_key = arr_key;
    unsigned int ui_key_size = sizeof(arr_key);
    *p_i_end_flg = FR_NO;
    i_position = bytebuff_getPosition(p_st_data);

    if (i_is_request == FR_YES)
    {
        snprintf(p_key, ui_key_size, "request.");
    }
    else
    {
        snprintf(p_key, ui_key_size, "response.");
    }
    p_key += strlen(p_key);
    ui_key_size -= strlen(p_key);

    /* 取得classID */
    i_ret = frkyro_read_var_int(p_st_data, FR_YES, &i_class_id);
    if (i_ret != FR_SUCC)
    {
        return FR_FAIL;
    }
    switch (i_class_id)
    {
        case FRKYRO_NULL:
            *p_i_end_flg = FR_YES;
            return FR_SUCC;

        /* 取得className */
        case FRKYRO_CLASS_NAME:
            i_ret = frkyro_read_var_int(p_st_data, FR_YES, &i_name_id);
            if (i_ret != FR_SUCC)
            {
                return FR_FAIL;
            }
            if (i_name_id != FRKYRO_NULL)
            {
                //TODO 无法仅从数据包中兼容解析是否带有className,
                //TODO 现将nameID是非0的当做无className解析
                //snprintf(p_key, ui_key_size, "classNameID");
                //i_ret = frreport_body_l7_add_int(p_st_body_data, arr_key, i_name_id);
                //return i_ret;
                bytebuff_setPosition(p_st_data, i_position);
                return FR_SUCC;
            }
            /* 取得className */
            i_ret = frkyro_read_string(p_st_data, &p_class_name);
            if (i_ret != FR_SUCC)
            {
                return FR_FAIL;
            }
            snprintf(p_key, ui_key_size, "className");
            i_ret = frreport_body_l7_add_str(p_st_body_data, arr_key, p_class_name ? p_class_name : "");
            if (i_ret != FR_SUCC && p_class_name)
            {
                frfree(p_class_name);
            }
            return i_ret;

        /* 注册过的classID*/
        default:
            snprintf(p_key, ui_key_size, "classID");
            i_ret = frreport_body_l7_add_int(p_st_body_data, arr_key, i_class_id);
            return i_ret;
    }
}

/*******************************************************************************
*  FUNC     :  读取object
*  ARGS     :  p_st_data(Frbyte_Packet *)
*           :  p_st_body_data(上报内容)
*           :  i_is_request(是否是request)
*  RTN      :  FR_SUCC  (success)
*              FR_FAIL  (failed)
*  NOTE     :
*******************************************************************************/
int frkyro_read_object(Frbyte_Packet *p_st_data
                       , Frreport_body_data *p_st_body_data
                       , int i_is_request)
{
    int i_ret = FR_SUCC;
    int i_id = 0;
    int i_mem_type = 0;
    int i_var_int = 0;
    float f_value = 0;
    double d_value = 0;
    short s_value = 0;
    long l_value = 0;
    char arr_key[256] = {0};
    char *p_key = arr_key;
    char *p_str_value = NULL;
    unsigned int ui_key_size = sizeof(arr_key);

    if (i_is_request == FR_YES)
    {
        snprintf(p_key, ui_key_size, "request.");
    }
    else
    {
        snprintf(p_key, ui_key_size, "response.");
    }
    p_key += strlen(p_key);
    ui_key_size -= strlen(p_key);

    //TODO由于网络传输过程中不传输class描述，根据实际情况单独传输java底层类
    //例如int，double的情形较少，故此处默认是自定义的类，所以读取mapID
    i_ret = frkyro_read_var_int(p_st_data, FR_YES, &i_id);
    if (i_ret != FR_SUCC)
    {
        return FR_FAIL;
    }
    /* 非NULL直接return，REF */
    if (i_id != FRKYRO_NOT_NULL)
    {
        return FR_SUCC;
    }

    /* 解析object成员 */
    i_ret = frkyro_read_var_int(p_st_data, FR_YES, &i_mem_type);
    if (i_ret != FR_SUCC)
    {
        return FR_FAIL;
    }

    //TODO 由于class信息不存在与数据包中，无法解析基础类型之外的诸如
    //class，数组，class嵌套之类复杂的class,近支持单层，且只有基础类型的class
    switch (i_mem_type)
    {
        //int
        case 2:
            i_ret = frkyro_read_var_int(p_st_data, FR_NO, &i_var_int);
            if (i_ret != FR_SUCC)
            {
                return FR_FAIL;
            }
            snprintf(p_key, ui_key_size, "intValue");
            i_ret = frreport_body_l7_add_int(p_st_body_data, arr_key, i_var_int);
            if (i_ret != FR_SUCC)
            {
                return FR_FAIL;
            }
            break;

        //string
        case 3:
            i_ret = frkyro_read_string(p_st_data, &p_str_value);
            if (i_ret != FR_SUCC)
            {
                return FR_FAIL;
            }
            snprintf(p_key, ui_key_size, "stringValue");
            i_ret = frreport_body_l7_add_str(p_st_body_data, arr_key, p_str_value);
            if (p_str_value)
            {
                frfree(p_str_value);
                p_str_value = NULL;
            }
            if (i_ret != FR_SUCC)
            {
                return FR_FAIL;
            }
            break;

        //float
        case 4:
            i_ret = frkyro_read_float(p_st_data, &f_value);
            if (i_ret != FR_SUCC)
            {
                return FR_FAIL;
            }
            snprintf(p_key, ui_key_size, "floatValue");
            i_ret = frreport_body_l7_add_float(p_st_body_data, arr_key, f_value);
            if (i_ret != FR_SUCC)
            {
                return FR_FAIL;
            }
            break;

        //byte
        case 6:
            i_ret = frkyro_read_byte(p_st_data, &p_str_value);
            if (i_ret != FR_SUCC)
            {
                return FR_FAIL;
            }
            snprintf(p_key, ui_key_size, "byteValue");
            i_ret = frreport_body_l7_add_str(p_st_body_data, arr_key, p_str_value);
            frfree(p_str_value);
            p_str_value = NULL;
            if (i_ret != FR_SUCC)
            {
                return FR_FAIL;
            }
            break;

        //char
        case 7:
            i_ret = frkyro_read_char(p_st_data, &p_str_value);
            if (i_ret != FR_SUCC)
            {
                return FR_FAIL;
            }
            snprintf(p_key, ui_key_size, "charValue");
            i_ret = frreport_body_l7_add_str(p_st_body_data, arr_key, p_str_value);
            frfree(p_str_value);
            p_str_value = NULL;
            if (i_ret != FR_SUCC)
            {
                return FR_FAIL;
            }
            break;

        //short
        case 8:
            i_ret = frkyro_read_short(p_st_data, &s_value);
            if (i_ret != FR_SUCC)
            {
                return FR_FAIL;
            }
            snprintf(p_key, ui_key_size, "shortValue");
            i_ret = frreport_body_l7_add_int(p_st_body_data, arr_key, (int)s_value);
            if (i_ret != FR_SUCC)
            {
                return FR_FAIL;
            }
            break;

        //long
        case 9:
            i_ret = frkyro_read_var_long(p_st_data, FR_NO, &l_value);
            if (i_ret != FR_SUCC)
            {
                return FR_FAIL;
            }
            snprintf(p_key, ui_key_size, "longValue");
            i_ret = frreport_body_l7_add_long(p_st_body_data, arr_key, l_value);
            if (i_ret != FR_SUCC)
            {
                return FR_FAIL;
            }
            break;

        //double
        case 10:
            i_ret = frkyro_read_double(p_st_data, &d_value);
            if (i_ret != FR_SUCC)
            {
                return FR_FAIL;
            }
            snprintf(p_key, ui_key_size, "doubleValue");
            i_ret = frreport_body_l7_add_double(p_st_body_data, arr_key, d_value);
            if (i_ret != FR_SUCC)
            {
                return FR_FAIL;
            }
            break;

        default:
            frdbg("unsupport");
            return FR_FAIL;
    }
}

/*******************************************************************************
*  FUNC     :  读取class和object
*  ARGS     :  p_st_data(Frbyte_Packet *)
*           :  p_st_body_data(上报内容)
*           :  i_is_request(是否是request)
*  RTN      :  FR_SUCC  (success)
*              FR_FAIL  (failed)
*  NOTE     :
*******************************************************************************/
int frkyro_read_class_object(Frbyte_Packet *p_st_data
                             , Frreport_body_data *p_st_body_data
                             , int i_is_request)
{
    int i_ret = FR_SUCC;
    int i_end_flg = FR_NO;

    /* read class */
    i_ret = frkyro_read_class(p_st_data, p_st_body_data, i_is_request, &i_end_flg);
    if (i_ret != FR_SUCC || i_end_flg == FR_YES)
    {
        return i_ret;
    }

    /* read object */
    i_ret = frkyro_read_object(p_st_data, p_st_body_data, i_is_request);
    return i_ret;
}
